package sv.gob.mh.dgii.dao.ruc;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import sv.gob.mh.dgii.common.Utils;
import sv.gob.mh.dgii.dao.hibernate.HibernateDaoNoCrudImpl;
import sv.gob.mh.dgii.model.RcRuc;
import sv.gob.mh.dgii.model.pojos.ruc.QueryRuc;
import sv.gob.mh.dgii.model.pojos.ruc.QueryRucResult;

@Repository
@Transactional
public class QueryRucDaoImpl extends HibernateDaoNoCrudImpl implements QueryRucDao {

	/**
	 * Metodo de busqueda para consulta ruc con paginacion incluida
	 */
	@Override
	public QueryRucResult search(QueryRuc query,int page, int pageSize,
								String sortProperty, String sortDirection,boolean calcularTotal) {		
		
		Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(RcRuc.class);
		//criteria.setCacheable(true);				
		
		if(!Utils.isNullOrEmpty(query.getNit())){			
			criteria.add(Restrictions.eq("nit", query.getNitClean()));
		}else{
			if(!Utils.isNullOrEmpty(query.getNitRaiz())){
				criteria.add(Restrictions.like("nit", query.getNitRaiz() + "%"));
			}
		}
		if(!Utils.isNullOrEmpty(query.getDui())){
			criteria.createAlias("rcDocIdentidads", "rcDoc");
			criteria.add(Restrictions.eq("rcDoc.ndocIdentidad", query.getDui()));
		}
		if(!Utils.isNullOrEmpty(query.getNrc())){
			criteria.createAlias("rcCaractTribs", "rcCaractTrib");
			criteria.add(Restrictions.eq("rcCaractTrib.id.ncaractTrib", query.getNrc()));
		}
		if(!Utils.isNullOrEmpty(query.getNomComerc())){
			criteria.createAlias("rcNomComercs", "rcNomComerc");
			criteria.add(Restrictions.eq("rcNomComercs.snomComercial", query.getNomComerc()));
		}
		if(!Utils.isNullOrEmpty(query.getTipoContribuyente())){
			criteria.createAlias("tbTipoContrib", "tbTipoContrib");
			if(query.getTipoContribuyente().equals("T")){ //todos
				criteria.add(Restrictions.in("tbTipoContrib.id.cclase", new String[]{"J","N"}));
			}else{
				criteria.add(Restrictions.eq("tbTipoContrib.id.cclase", query.getTipoContribuyente()));
			}
		}
                
                
                
                if(!Utils.isNullOrEmpty(query.getTbPais()) && 
                   query.getTbPais().getCpais().equalsIgnoreCase("9300") && 
                   !Utils.isNullOrEmpty(query.getTbMunicipio()) &&
                   !Utils.isNullOrEmpty(query.getTbMunicipio().getId()) &&
                   !Utils.isNullOrEmpty(query.getTbMunicipio().getId().getCdepartamento())){
                    
                    criteria.createAlias("tbMunicipio", "tbMunicipio");
                    criteria.add(Restrictions.eq("tbMunicipio.id", query.getTbMunicipio().getId()));
                }
                if(!Utils.isNullOrEmpty(query.getTbPais()) && 
                   !query.getTbPais().getCpais().equalsIgnoreCase("9300") ){
                        criteria.createAlias("tbPais", "tbPais");
			criteria.add(Restrictions.eq("tbPais", query.getTbPais()));
		}
		if(!Utils.isNullOrEmpty(query.getS1apeRasoc())){
			criteria.add(Restrictions.eq("s1apeRasoc", query.getS1apeRasoc()));
		}
		if(!Utils.isNullOrEmpty(query.getS2apeAbrev())){
			criteria.add(Restrictions.eq("s2apeAbrev", query.getS2apeAbrev()));
		}
		if(!Utils.isNullOrEmpty(query.getSnombres())){
			criteria.add(Restrictions.like("snombres", "%"+query.getSnombres()+"%"));
		}
		if(!Utils.isNullOrEmpty(query.getFnacConstStr())){
			criteria.add(Restrictions.eq("fnacConst", query.getFnacConstStr()));
		}

		Long count = 0L;
		if(calcularTotal){
			count = (Long)criteria.setProjection(Projections.rowCount()).uniqueResult(); 		
			//System.out.println("Total Results:" + count);
			criteria.setProjection(null);
			criteria.setResultTransformer( Criteria.ROOT_ENTITY );
		}
		

		
		// inicio de paginacion		
		criteria.setFirstResult((page - 1) * pageSize);
		criteria.setMaxResults(pageSize);
		criteria.setFetchSize(pageSize);
				
		if(Utils.isNullOrEmpty(sortProperty)){
		        	sortProperty = "nit";
		}
		if(Utils.isNullOrEmpty(sortDirection)){
		        	sortDirection = "asc";
		}
		if("desc".equalsIgnoreCase(sortDirection)){
		        	criteria.addOrder(Order.desc(sortProperty));
		}else{
		        	criteria.addOrder(Order.asc(sortProperty));
		}
		//fin de paginacion
		
		
		return new QueryRucResult(count, criteria.list());
	}
        
        @Override
        public RcRuc obtenerRucPorNIT(String nit){
            String jpql = "SELECT o FROM RcRuc o LEFT JOIN FETCH o.tbTipoContrib tc LEFT JOIN FETCH tc.tbClaseContrib "
                                    + "LEFT JOIN FETCH o.rcActEcos "
                                    + "WHERE o.nit = :nit";
            Query q = getSessionFactory().getCurrentSession().createQuery(jpql);
            q.setParameter("nit", nit);
            return (RcRuc) q.uniqueResult();
        }
        
}
